function varargout = PIDOptimizerGUI(varargin)
    % PIDOPTIMIZERGUI MATLAB code for PIDOptimizerGUI.fig
    %      PIDOPTIMIZERGUI, by itself, creates a new PIDOPTIMIZERGUI or raises the existing
    %      singleton*.
    %
    %      H = PIDOPTIMIZERGUI returns the handle to a new PIDOPTIMIZERGUI or the handle to
    %      the existing singleton*.
    %
    %      PIDOPTIMIZERGUI('CALLBACK',hObject,eventData,handles,...) calls the local
    %      function named CALLBACK in PIDOPTIMIZERGUI.M with the given input arguments.
    %
    %      PIDOPTIMIZERGUI('Property','Value',...) creates a new PIDOPTIMIZERGUI or raises the
    %      existing singleton*.  Starting from the left, property value pairs are
    %      applied to the GUI before PIDOptimizerGUI_OpeningFcn gets called.  An
    %      unrecognized property name or invalid value makes property application
    %      stop.  All inputs are passed to PIDOptimizerGUI_OpeningFcn via varargin.
    %
    %      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
    %      instance to run (singleton)".
    %
    % See also: GUIDE, GUIDATA, GUIHANDLES
    
    % Edit the above text to modify the response to help PIDOptimizerGUI
    
    % Last Modified by GUIDE v2.5 12-Feb-2019 12:24:15
    
    % Begin initialization code - DO NOT EDIT
    gui_Singleton = 1;
    gui_State = struct('gui_Name',       mfilename, ...
        'gui_Singleton',  gui_Singleton, ...
        'gui_OpeningFcn', @PIDOptimizerGUI_OpeningFcn, ...
        'gui_OutputFcn',  @PIDOptimizerGUI_OutputFcn, ...
        'gui_LayoutFcn',  [] , ...
        'gui_Callback',   []);
    if nargin && ischar(varargin{1})
        gui_State.gui_Callback = str2func(varargin{1});
    end
    
    if nargout
        [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
    else
        gui_mainfcn(gui_State, varargin{:});
    end
    % End initialization code - DO NOT EDIT
end

% --- Executes just before PIDOptimizerGUI is made visible.
function PIDOptimizerGUI_OpeningFcn(hObject, eventdata, handles, varargin)
    % This function has no output args, see OutputFcn.
    % hObject    handle to figure
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)
    % varargin   command line arguments to PIDOptimizerGUI (see VARARGIN)
    
    
    % Choose default command line output for PIDOptimizerGUI
    handles.output = hObject;
    
    % Update handles structure
    guidata(hObject, handles);
    
    % UIWAIT makes PIDOptimizerGUI wait for user response (see UIRESUME)
    % uiwait(handles.figure1);    
    
%     initialization(handles, 1, ziTC2BW(12, 1));
end

% --- Outputs from this function are returned to the command line.
function varargout = PIDOptimizerGUI_OutputFcn(hObject, eventdata, handles)
    % varargout  cell array for returning output args (see VARARGOUT);
    % hObject    handle to figure
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Get default command line output from handles structure
    varargout{1} = handles.output;
end
%%
function initialization(handles, order, bw)
    hObject = handles.figHdl;
    handles.plant = EquipmentControl.FeedBackOptimization.LTIUnit.LowPassFilter(order, bw);
    filterOrder = str2double(handles.filterOrder.String); filterBW = str2double(handles.filterBW.String); 
    handles.filter = EquipmentControl.FeedBackOptimization.LTIUnit.LowPassFilter(filterOrder, filterBW);
    handles.tune = EquipmentControl.FeedBackOptimization.PIDOptimizer(handles.plant, handles.filter);
    handles.autoUpdate.Value = false;
    
    guidata(hObject, handles);

    hObject.('WindowButtonMotionFcn') = @mouseMove; % @(objFig, eventFig) mouseMove(objFig, eventFig);
    hObject.('WindowButtonDownFcn') =  @mouseClick; %@(objFig, eventFig) mouseClick(objFig, eventFig);
    hObject.('WindowKeyPressFcn') = @keyPress; %@(obj, event) keyPress(obj, event);
end

function update_response_bode(handles, pVal, iVal, dVal)
    handles.tune.setController(pVal, iVal, dVal);
    handles.tune.response('axes', handles.axesStep, 'tList', handles.timeList);
    handles.tune.bodePlot('axesMag', handles.axesMag, 'axesPhase', handles.axesPhase);
end
%% Mouse and Keyboard Events
function mouseMove(~, ~)
    handles=guidata(gcbo);
    curr_point = get(handles.axesMain, 'CurrentPoint');
    pVal = curr_point(1, 1); iVal = curr_point(1, 2); dVal = str2double(handles.ValueD.String);
    
    if pVal > handles.rangePValue(2)
        pVal = handles.rangePValue(2);
    elseif pVal < handles.rangePValue(1)
        pVal = handles.rangePValue(1);
    end
    
    if iVal > handles.rangeIValue(2)
        iVal = handles.rangeIValue(2);
    elseif iVal < handles.rangeIValue(1)
        iVal = handles.rangeIValue(1);
    end
    
    if handles.autoUpdate.Value 
        handles.axesMain.Children(1).XData=pVal;
        handles.axesMain.Children(1).YData=iVal;
        title(handles.axesMain, sprintf('P=%3.2f, I=%3.2f, D=%3.2f', [pVal, iVal, dVal]));
        update_response_bode(handles, pVal, iVal, dVal);
    end
end

function mouseClick(~, ~)    
    handles=guidata(gcbo);
    curr_point = get(handles.axesMain, 'CurrentPoint');
    pVal = curr_point(1, 1); iVal = curr_point(1, 2);
    dVal = str2double(handles.ValueD.String);
    
    if pVal > handles.rangePValue(2)
        pVal = handles.rangePValue(2);
    elseif pVal < handles.rangePValue(1)
        pVal = handles.rangePValue(1);
    end
    
    if iVal > handles.rangeIValue(2)
        iVal = handles.rangeIValue(2);
    elseif iVal < handles.rangeIValue(1)
        iVal = handles.rangeIValue(1);
    end
    
    update_response_bode(handles, pVal, iVal, dVal);
    
    handles.ValueP.String = sprintf('%3.2f', pVal);
    handles.ValueI.String = sprintf('%3.2f', iVal);
    
    handles.axesMain.Children(1).XData=pVal;
    handles.axesMain.Children(1).YData=iVal;
    title(handles.axesMain, sprintf('P=%3.2f, I=%3.2f, D=%3.2f', [pVal, iVal, dVal]));
end

function keyPress(~, event)
    handles=guidata(gcbo);
    switch event.Key
        case 'a'
            handles.autoUpdate.Value = ~handles.autoUpdate.Value;
        otherwise
            % do nothing
    end
    guidata(gcbo, handles);
end

%% GUIDE Controller Events
% --- Executes on button press in autoUpdate.
function autoUpdate_Callback(hObject, eventdata, handles)
% hObject    handle to autoUpdate (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of autoUpdate
end



function ValueP_Callback(hObject, eventdata, handles)
% hObject    handle to ValueP (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of ValueP as text
%        str2double(get(hObject,'String')) returns contents of ValueP as a double
end

% --- Executes during object creation, after setting all properties.
function ValueP_CreateFcn(hObject, eventdata, handles)
% hObject    handle to ValueP (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function ValueI_Callback(hObject, eventdata, handles)
% hObject    handle to ValueI (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of ValueI as text
%        str2double(get(hObject,'String')) returns contents of ValueI as a double
end

% --- Executes during object creation, after setting all properties.
function ValueI_CreateFcn(hObject, eventdata, handles)
% hObject    handle to ValueI (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function ValueD_Callback(hObject, eventdata, handles)
% hObject    handle to ValueD (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of ValueD as text
%        str2double(get(hObject,'String')) returns contents of ValueD as a double
    dVal = str2double(get(hObject,'String'));
    handles.SliderDValue.Value = dVal;
end

% --- Executes during object creation, after setting all properties.
function ValueD_CreateFcn(hObject, eventdata, handles)
% hObject    handle to ValueD (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function tList_Callback(hObject, eventdata, handles)
% hObject    handle to tList (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of tList as text
%        str2double(get(hObject,'String')) returns contents of tList as a double

    %tList = eval(get(hObject,'String'));
    
    pVal = str2double(handles.ValueP.String);
    iVal = str2double(handles.ValueI.String);
    dVal = str2double(handles.ValueD.String);
    handles.timeList = eval(handles.tList.String);
    update_response_bode(handles, pVal, iVal, dVal)
    guidata(hObject, handles);
end

% --- Executes during object creation, after setting all properties.
function tList_CreateFcn(hObject, eventdata, handles)
% hObject    handle to tList (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
    if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
    end
    handles.timeList = eval(get(hObject,'String'));
    guidata(hObject, handles);
end

function wList_Callback(hObject, eventdata, handles)
% hObject    handle to wList (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of wList as text
%        str2double(get(hObject,'String')) returns contents of wList as a double
end

% --- Executes during object creation, after setting all properties.
function wList_CreateFcn(hObject, eventdata, handles)
% hObject    handle to wList (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end

% --- Executes on button press in updateChart.
function updateChart_Callback(hObject, eventdata, handles)
% hObject    handle to updateChart (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%     handles=guidata(gcbo);
    pval = handles.optimalPValue;
    ival = handles.optimalIValue;
    dval = handles.optimalDValue;
    handles.ValueP.String = sprintf('%3.2f', pval);
    handles.ValueI.String = sprintf('%3.2f', ival);
    handles.ValueD.String = sprintf('%3.2f', dval);

    update_response_bode(handles, pval, ival, dval);

    handles.axesMain.Children(1).XData=pval;
    handles.axesMain.Children(1).YData=ival;
    title(handles.axesMain, sprintf('P=%3.2f, I=%3.2f, D=%3.2f', [pval, ival, dval]));

end

% --- Executes on selection change in plotType.
function plotType_Callback(hObject, eventdata, handles)
% hObject    handle to plotType (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns plotType contents as cell array
%        contents{get(hObject,'Value')} returns selected item from plotType
end

% --- Executes during object creation, after setting all properties.
function plantName_CreateFcn(hObject, eventdata, handles)
% hObject    handle to plantName (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function filterOrder_Callback(hObject, eventdata, handles)
% hObject    handle to filterOrder (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of filterOrder as text
%        str2double(get(hObject,'String')) returns contents of filterOrder as a double
end

% --- Executes during object creation, after setting all properties.
function filterOrder_CreateFcn(hObject, eventdata, handles)
% hObject    handle to filterOrder (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function filterBW_Callback(hObject, eventdata, handles)
% hObject    handle to filterBW (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of filterBW as text
%        str2double(get(hObject,'String')) returns contents of filterBW as a double
end

% --- Executes during object creation, after setting all properties.
function filterBW_CreateFcn(hObject, eventdata, handles)
% hObject    handle to filterBW (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end

% --- Executes on slider movement.
function SliderDValue_Callback(hObject, eventdata, handles)
% hObject    handle to SliderDValue (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
    dval = get(hObject,'Value');
    handles.ValueD.String = sprintf('%3.2f', dval);
    
    pVal = str2double(handles.ValueP.String);
    iVal = str2double(handles.ValueI.String);
    update_response_bode(handles, pVal, iVal, dval)
end

% --- Executes during object creation, after setting all properties.
function SliderDValue_CreateFcn(hObject, eventdata, handles)
% hObject    handle to SliderDValue (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end
end


% --- Executes on button press in initButton.
function initButton_Callback(hObject, eventdata, handles)
% hObject    handle to initButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)   
    initialization(handles, 1, ziTC2BW(12, 1) );
    handles = guidata(handles.figure1);
    
    tList = eval(handles.tList.String);
    weight =  str2double(handles.weight.String);
    method = handles.method.String{handles.method.Value};
    
    c=handles.tune.optimPID('type', 'PID', 'costfun', method, 'weight', weight, 'tList', tList);
    [pval, ival, dval] = c.getPIDValues();
    
    handles.optimalPValue = pval;
    handles.optimalIValue = ival;
    handles.optimalDValue = dval;
    handles.rangePValue = minmax([0, 5.0*pval]);
    handles.rangeIValue = minmax([0, 5.0*ival]);
    handles.rangeDValue = minmax([0, 5.0*dval]);
    
    handles.ValueP.String = sprintf('%3.2f', pval);
    handles.ValueI.String = sprintf('%3.2f', ival);
    handles.ValueD.String = sprintf('%3.2f', dval);
    
    handles.SliderDValue.Min = handles.rangeDValue(1);
    handles.SliderDValue.Max = handles.rangeDValue(2);
    handles.SliderDValue.Value = dval;
    handles.SliderDValue.SliderStep = abs(dval)*[0.01, 0.1];
    
    handles.tune.PIChart('axes', handles.axesMain, ...
                         'minP', handles.rangePValue(1), ...
                         'maxP', handles.rangePValue(2), ...
                         'minI', handles.rangeIValue(1), ...
                         'maxI', handles.rangeIValue(2),...
                         'dValue', dval, ...
                         'weight',weight);
    handles.axesMain.Children(2).XData=pval;
    handles.axesMain.Children(2).YData=ival;
    title(handles.axesMain, sprintf('P=%3.2f, I=%3.2f', [pval, ival]));
    update_response_bode(handles, pval, ival, dval);
    
    guidata(hObject, handles);
end



function weight_Callback(hObject, eventdata, handles)
% hObject    handle to weight (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of weight as text
%        str2double(get(hObject,'String')) returns contents of weight as a double
    handles.weightValue = str2double(get(hObject,'String'));
    guidata(hObject, handles);
end

% --- Executes during object creation, after setting all properties.
function weight_CreateFcn(hObject, eventdata, handles)
% hObject    handle to weight (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


% --- Executes during object creation, after setting all properties.
function figure1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
    handles.figHdl = hObject;
    guidata(hObject, handles);
end


% --- Executes on selection change in method.
function method_Callback(hObject, eventdata, handles)
% hObject    handle to method (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns method contents as cell array
%        contents{get(hObject,'Value')} returns selected item from method
end

% --- Executes during object creation, after setting all properties.
function method_CreateFcn(hObject, eventdata, handles)
% hObject    handle to method (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end

